﻿//  ***** Guidance generated code © Catharsis ***** //
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using Mulala.Cavan.Core.Extension;
using Mulala.Cavan.Application.Seedwork;
using Mulala.Cavan.Core.Persistent;
using Mulala.Cavan.Domain.Seedwork;
using Mulala.Cavan.Core.Message;
using Mulala.Cavan.Core.MyException;

namespace Mulala.Cavan.Application.MainBoundedContext
{
    public abstract class BaseAppService<T, TSearch>
        : BaseAppService<T, TSearch, IRepository<T, TSearch>>
        where T : class, IPersistentObjectWithTypedId<int>, new()
        where TSearch : class, ISearch<int>, new()
    {
    }

    /// <summary>
    ///     Base class for the standard Entities with int ID
    ///     Expected template must be object with public constructor.
    ///     If you need BaseFacade[T] with ID int without public constructor (like interface for future reuse)
    ///     simply use its ancesstor BaseFacade[T,IdT] and do not forget to instantiate Example
    /// </summary>
    /// <typeparam name = "T"></typeparam>
    /// <typeparam name = "TDao"></typeparam>
    /// <typeparam name = "TValidator"></typeparam>
    /// <typeparam name = "TSearch"></typeparam>
    public abstract class BaseAppService<T, TSearch, TRepository>
        : BaseAppService<T, int, TSearch, TRepository>
        where T : class, IPersistentObjectWithTypedId<int>, new()
        where TRepository : class, IRepository<T, TSearch>
        where TSearch : class,ISearch<int>, new()
    {

    }

    public abstract class BaseAppService<T, TID, TSearch, TRepository>
        : ReadAppService<T, TID, TSearch, TRepository>, IBaseAppService<T, TID, TSearch>
        where T : class, IPersistentObjectWithTypedId<TID>
        where TRepository : class, IRepository<T, TSearch>
        where TSearch : class, ISearch<TID>
    {
        #region constructor
        protected BaseAppService()
        {
        }
        #endregion constructor

        #region IWriteFacade
        public virtual BoolGenericResult<T> Add(T entity)
        {
            BoolGenericResult<T> result = new BoolGenericResult<T>();
            if (entity.IsNull())
            {
                Messages.AddError(this, "", "", typeof(T).Name);
                result.Object = default(T);
                return result;
            }
            try
            {
                Repository.Save(entity);
                result.Object = entity;
                return result;
            }
            catch (DaoException)
            {
                throw; 
            }
            catch (Exception ex)
            {
                Messages.AddException(this, "异常", ex);
                result.IsSuccess = false;
                return result;
            }
        }

        public virtual BoolGenericResult<T> Update(T entity)
        {
            BoolGenericResult<T> result = new BoolGenericResult<T>();
            if (entity.IsNull())
            {
                Messages.AddError(this, "", "", typeof(T).Name);
                result.Object = default(T);
                return result;
            }
            try
            {
                Repository.Update(entity);
                result.Object = entity;
                return result;
            }
            catch (DaoException)
            {
                throw; 
            }
            catch (Exception ex)
            {
                Messages.AddException(this, "异常", ex);
                result.IsSuccess = false;
                return result;
            }
        }

        public virtual BoolGenericResult<T> Delete(T entity)
        {
            BoolGenericResult<T> result = new BoolGenericResult<T>();
            if (entity.IsNull())
            {
                Messages.AddError(this, "", "", "空对象");
                result.IsSuccess = false;
                return result;
            }
            try
            {
                Repository.Delete(entity);
                result.Object = entity;
                return result;
            }
            catch (DaoException)
            {
                throw; 
            }
            catch (Exception ex)
            {
                Messages.AddException(this, "异常", ex);
                result.IsSuccess = false;
                return result;
            }
        }

        public BoolGenericResult<T> AddOrUpdate(T entity)
        {
            BoolGenericResult<T> result = new BoolGenericResult<T>();
            if (entity.IsNull())
            {
                Messages.AddError(this, "", "", typeof(T).Name);
                result.Object = default(T);
                return result;
            }
            try
            {
                Repository.SaveOrUpdate(entity);
                result.Object = entity;
                return result;
            }
            catch (DaoException)
            {
                throw;
            }
            catch (Exception ex)
            {
                Messages.AddException(this, "异常", ex);
                result.IsSuccess = false;
                return result;
            }
        }
        #endregion IWriteFacade
    }
}